package com.kding.cos;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.tencent.cos.xml.CosXmlServiceConfig;
import com.tencent.cos.xml.CosXmlSimpleService;
import com.tencent.cos.xml.exception.CosXmlClientException;
import com.tencent.cos.xml.exception.CosXmlServiceException;
import com.tencent.cos.xml.model.object.PutObjectRequest;
import com.tencent.cos.xml.model.object.PutObjectResult;
import com.tencent.qcloud.core.auth.QCloudCredentialProvider;
import com.tencent.qcloud.core.auth.ShortTimeCredentialProvider;

import java.io.File;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author lishaojie on 2019/11/22
 */
public class KdingCosManager {
    private static final String TAG = "KdingCosManager";
    /**
     * im 日志目录
     */
    private static String IM_LOG_PATH = "/tencent/imsdklogs/%s/";
    /**
     * 直播日志目录
     */
    private static final String LIVE_LOG_PATH = "/log/tencent/liteav/";
    private static final String LIVE_LOG_DATA_PATH = "/Android/data/%s/files" + LIVE_LOG_PATH;

    private static String secretId = "AKIDzzKcIxgqqy2GOd9awCNakuTZ2YljiOcC";
    private static String secretKey = "mp1fF7kIuIJ3faLC6eFNw8r3QL6UHej6";
    private static String region = "ap-guangzhou";
    private static String bucket = "android-txlog-1252295517";
    private static CosXmlServiceConfig serviceConfig;
    private static QCloudCredentialProvider credentialProvider = new ShortTimeCredentialProvider(secretId, secretKey, 300);
    private static String appName;
    private static Context mContext;
    private static String packageName;
    private static String userId;
    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1,
            30L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>());


    public static void putTXCOS(final Application context, String userid) {
        init(context, userid);
        final String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        putBitch(rootPath + LIVE_LOG_PATH, null, false);
        Log.d(TAG, "run: " + Thread.currentThread() + "path = LIVE_LOG_PATH");
        putBitch(String.format(rootPath + LIVE_LOG_DATA_PATH, packageName), null, false);
        Log.d(TAG, "run: " + Thread.currentThread() + "path = LIVE_LOG_DATA_PATH");
        putBitch(String.format(rootPath + IM_LOG_PATH, packageName.replace(".", File.separator)), null, true);
        Log.d(TAG, "run: " + Thread.currentThread() + "path = IM_LOG_PATH");


    }

    /**
     * 初始化区域以及bucket，默认可以使用
     *
     * @param bucketId
     * @param reg
     */
    public static void initCosConfig(String bucketId, String reg) {
        bucket = bucketId;
        region = reg;


    }

    /**
     * @param context
     * @param userid
     * @param srcPath       需要上传的文件路径
     * @param specifyFolder 指定上传的目录
     */

    public static void putTXCOS(final Application context, String userid, final String srcPath, final String specifyFolder) {
        init(context, userid);
        final File logFile = new File(srcPath);
        if (logFile.exists()) {
            if (logFile.isDirectory()) {
                putBitch(srcPath, specifyFolder, false);
            } else {
                putSingle(logFile, specifyFolder, false);
            }

        }
    }

    private static void init(final Application context, String userid) {
        if (context == null) {
            throw new IllegalArgumentException("context must not null");
        }
        mContext = context;
        userId = userid;
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        if (TextUtils.isEmpty(packageName)) {
            packageName = mContext.getPackageName();
        }
        serviceConfig = new CosXmlServiceConfig.Builder()
                .setRegion(region)
                .setDebuggable(true)
                .builder();
    }

    /**
     * 是否是im
     *
     * @param specifyFolder 文件夹
     * @param isIm          是否是im
     * @return
     */
    private static String getCosPath(File logFile, String specifyFolder, boolean isIm) {
        StringBuilder cosPath = new StringBuilder(getAppName(mContext));
        cosPath.append(File.separator)
                .append(userId)
                .append("_")
                .append(android.os.Build.BRAND)
                .append("_")
                .append(android.os.Build.MODEL)
                .append("_")
                .append(TextUtils.isEmpty(specifyFolder) ? isIm ? "IM" : "TXLIVE" : specifyFolder)
                .append(File.separator)
                .append(logFile.getName());
        return cosPath.toString();
    }

    /**
     * 批量上传
     */
    private static void putBitch(String path, String specifyFolder,
                                 boolean isIm) {
        File logFileParent = new File(path);
        if (logFileParent.exists() && logFileParent.isDirectory()) {
            File[] logFiles = logFileParent.listFiles();
            if (logFiles != null && logFiles.length > 0) {
                for (File logFile : logFiles) {
                    if (checkLogFile(logFile)) {
                        putSingle(logFile, specifyFolder, isIm);
                    }
                }
                //目录下的文件全部上传成功再执行删除
//                if (i == logFiles.length) {
//                    deleteUploaded(logFiles);
//                }
            }
        }


    }

    /**
     * 删除已经上传过的文件
     */

    private static void deleteUploaded(File logFile) {
        Log.d(TAG, "deleteUploaded: " + logFile.getName());
        logFile.delete();
    }

    /**
     * 校验日志文件的合法性
     *
     * @param logFile
     * @return
     */
    private static boolean checkLogFile(File logFile) {
        return logFile.exists()
                && !logFile.isDirectory()
                && logFile.length() > 0;
    }

    /**
     * 上传单个
     */
    private static void putSingle(final File srcPath, final String specifyFolder, final boolean isIm) {
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "putSingle: srcPath = " + srcPath.getAbsolutePath());
                String cosPath = getCosPath(srcPath, specifyFolder, isIm);
                Log.d(TAG, "putSingle: cosPath = " + cosPath);
                final CosXmlSimpleService cosXmlService = new CosXmlSimpleService(mContext, serviceConfig, credentialProvider);
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, cosPath, srcPath.getAbsolutePath());
                try {
                    // 使用同步回调上传
                    PutObjectResult putObjectResult = cosXmlService.putObject(putObjectRequest);
                    Log.d(TAG, "putSingle: putObjectResult = " + putObjectResult.accessUrl);
                    deleteUploaded(srcPath);
                } catch (CosXmlClientException e) {
                    Log.d(TAG, "putSingle: onFail = " + e.errorCode);
                } catch (CosXmlServiceException e) {
                    Log.d(TAG, "putSingle: onFail = " + e.getErrorCode());
                }
            }
        });

    }

    /**
     * 获取应用程序名称
     */
    private static String getAppName(Context context) {
        try {
            if (!TextUtils.isEmpty(appName)) {
                return appName;
            }
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(
                    context.getPackageName(), 0);
            int labelRes = packageInfo.applicationInfo.labelRes;
            return appName = context.getResources().getString(labelRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "unknow";
    }

    /**
     * 停止上报
     */
    public static void cancelCos() {
        threadPoolExecutor.shutdownNow();
    }


}
